import {
	window,
	commands,
	workspace,
	QuickPick,
	QuickPickItem,
	ExtensionContext,
	StatusBarAlignment,
} from 'vscode';
import { Fund, status, search, FundRealTimeDate } from './fund';
import * as schedule from 'node-schedule';


type Action = (item: QuickPickItemAction) => void;
interface QuickPickItemAction extends QuickPickItem {
	action: Action;
	code: string;
}

interface Listen {
	code: string;
	name: string;
}

function setFundList(fundList: Fund[], action: Action, quickPick: QuickPick<QuickPickItemAction>) {
	const itemList: QuickPickItemAction[] = [];
	for (const fund of fundList) {
		itemList.push({
			action,
			label: fund.name,
			description: fund.type,
			code: fund.code,
		});
	}
	quickPick.value = '';
	quickPick.busy = false;
	quickPick.items = itemList;
	quickPick.placeholder = '选择要监听的基金';
	quickPick.show();
}

function setListenList(listenList: Listen[], action: Action, quickPick: QuickPick<QuickPickItemAction>) {
	const itemList: QuickPickItemAction[] = [];
	for (const item of listenList) {
		itemList.push({
			action,
			label: item.name,
			description: item.code,
			code: item.code,
		});
	}
	quickPick.value = '';
	quickPick.busy = false;
	quickPick.items = itemList;
	quickPick.placeholder = '选择要删除的基金';
	quickPick.show();
}

const rule = new schedule.RecurrenceRule();
rule.hour = [14];
rule.minute  = 40;

export async function activate(context: ExtensionContext) {
	const quickPick: QuickPick<QuickPickItemAction> = window.createQuickPick();
	quickPick.busy = false;
  quickPick.matchOnDetail = true;
	quickPick.canSelectMany = false;
	quickPick.matchOnDescription = true;
	quickPick.onDidAccept(async () => {
		const item = quickPick.selectedItems[0];
		if (!quickPick.busy && item.action) {
			quickPick.busy = true;
			await item.action(item);
		}
	});

	const selectCode = (() => {
		let index = 0;
		return () => {
			const codeList = context.globalState.get<string[]>('code') || [];
			if (codeList.length === 0) {
				return '';
			}
			if (index > codeList.length - 1 || !codeList[index]) {
				index = 0;
			}
			return codeList[index ++].split(':')[0];
		};
	})();

	const view = window.createStatusBarItem(StatusBarAlignment.Left);
	view.command = 'fund.switch';
	view.show();

	context.subscriptions.push(commands.registerCommand('fund.switch', async () => {
		const code = selectCode();
			if (code) {
				view.text = format(await status(code));
			} else {
				view.text = '当前未监听任何基金';
			}
	}));

	context.subscriptions.push(commands.registerCommand('fund.cancel', async () => {
		const list = (context.globalState.get<string[]>('code') || []).map((item) => {
			const [code, name] = item.split(':');
			return { code, name };
		});
		setListenList(list, async (item: QuickPickItemAction) => {
			const codeSet = new Set(context.globalState.get<string[]>('code') || []);
			codeSet.delete(`${ item.code }:${ item.label }`);
			context.globalState.update('code', [...codeSet]);
			window.showInformationMessage(`${ item.label } 已删除！`);
			quickPick.hide();
		}, quickPick);
	}));

	context.subscriptions.push(commands.registerCommand('fund.search', async () => {
		const keyword = await window.showInputBox({ placeHolder: '请输入关键字，基金代码、名称、拼音、缩写均可' }) || '';
		const list = await search(keyword);
		setFundList(list, async (item: QuickPickItemAction) => {
			const codeSet = new Set(context.globalState.get<string[]>('code') || []);
			codeSet.add(`${ item.code }:${ item.label }`);
			context.globalState.update('code', [...codeSet]);
			window.showInformationMessage(`${ item.label } 已添加监听！`);
			quickPick.hide();
		}, quickPick);
	}));

	setTimeout(async () => {
		while (workspace.getConfiguration('fund').get<boolean>('autoRun')) {
			const code = selectCode();
			if (code) {
				view.text = format(await status(code));
			} else {
				view.text = '当前未监听任何基金';
			}
			if (new Date().getHours() > 14) {
				break;
			}
			await sleep(120000);
		}
	}, 0);

	schedule.scheduleJob(rule, async () => {
		const codeList = (context.globalState.get<string[]>('code') || []).map((item) => {
			return item.split(':')[0];
		});
		for (const code of codeList) {
			window.showInformationMessage(format(await status(code)));
		}
	});
}

function sleep(interval: number) {
	return new Promise((resolve) => {
		setTimeout(resolve, interval);
	});
}

function format(info: FundRealTimeDate) {
	const formatStr = workspace.getConfiguration('fund').get<string>('format') || '';
	return formatStr
	.replace(/\{ *?fundcode\ *?}/g, info.fundcode)
		.replace(/\{ *?name\ *?}/g, info.name)
		.replace(/\{ *?jzrq\ *?}/g, info.jzrq)
		.replace(/\{ *?dwjz\ *?}/g, info.dwjz)
		.replace(/\{ *?gsz\ *?}/g, info.gsz)
		.replace(/\{ *?gszzl\ *?}/g, info.gszzl)
		.replace(/\{ *?gztime\ *?}/g, info.gszzl);
}

export function deactivate() {}
